package lionel.MyJMRI.MyTrain;

import java.util.List;
import java.util.ListIterator;

import jmri.jmrit.roster.Roster;
import jmri.jmrit.roster.RosterEntry;
import lionel.MyBrowser.MyBrowsableElement;
import lionel.MyBrowser.MyBrowsableList;

//
// Implements a MyBrowsableList over all available rosters
//
public class MyLocomotives implements MyBrowsableList {
	static org.apache.log4j.Category log = org.apache.log4j.Category.getInstance(MyLocomotives.class.getName());

	private MyLocomotive []mLocos = null;
	private int mCurLoc = 0, nLoopDecount;
	
	public MyLocomotives()
	{
		List<RosterEntry> allRosters = (List<RosterEntry>) Roster.instance().matchingList(null, null, null, null, null, null, null) ;
		if ((allRosters==null) || (allRosters.isEmpty()))
		{
			log.warn("Roster list is empty - Adding default rosters on DCC addresses 0 and 3");			
			RosterEntry entry0 = new RosterEntry();
			RosterEntry entry3 = new RosterEntry();
			entry0.setDccAddress("0");
			entry0.setModel("DC control");
			Roster.instance().addEntry(entry0 );
			entry3.setDccAddress("3");
			entry3.setModel("Default DCC control");
			Roster.instance().addEntry(entry3 );
			allRosters = (List<RosterEntry>) Roster.instance().matchingList(null, null, null, null, null, null, null) ;
		}
		int n = allRosters.size();
		if (n == 0)
			return;
		mLocos = new MyLocomotive[n];
		ListIterator<RosterEntry> allRostersIter = allRosters.listIterator();
		if (allRostersIter == null)
		{
			log.error("fillLocoArray() allRostersIter is null");
			return;
		}
		for (int i=0; i<n; i++)
		{
			RosterEntry roster = allRostersIter.next();
			if (roster == null)
			{
				log.error("fillLocoArray() roster is null");
				return;
			}
			mLocos[i] = new MyLocomotive(roster);
			if (mLocos[i] == null)
			{
				log.error("fillLocoArray() roster is null");
				return;
			}
		}
		mCurLoc = 0;
		nLoopDecount = mLocos.length;
	}
	
	public MyBrowsableElement getNext() {
		if (mLocos.length == 0)
			return null; // Shouldn't happen
		if (mLocos.length == 1)
			return mLocos[0];
		mCurLoc++;
		if (mCurLoc >= mLocos.length)
			mCurLoc = 0;
		if ( MyTrainsInstance.getInstance().contains(mLocos[mCurLoc]) )
		{
			if (nLoopDecount == 0)
			{
				log.info("All locomotives are running, nothing in spare");
				return null;
			}
			nLoopDecount--;
			return getNext();
		}
		nLoopDecount = mLocos.length;
		return mLocos[mCurLoc];
	}

	public MyBrowsableElement getPrev( ) {
		if (mLocos.length == 0)
			return null; // Shouldn't happen
		if (mLocos.length == 1)
			return mLocos[0];
		mCurLoc--;
		if (mCurLoc < 0)
			mCurLoc = mLocos.length-1;
		if ( MyTrainsInstance.getInstance().contains(mLocos[mCurLoc]) )
		{
			if (nLoopDecount == 0)
			{
				log.info("All locomotives are running, nothing in spare");
				return null;
			}
			nLoopDecount--;
			return getPrev();
		}
		nLoopDecount = mLocos.length;
		return mLocos[mCurLoc];
	}

	public MyBrowsableElement select() {
		synchronized ( MyTrainsInstance.getInstance() )
		{
			if ( MyTrainsInstance.getInstance().contains(mLocos[mCurLoc]) )
				return null;
			log.debug(mLocos[mCurLoc].getRoster().getDccAddress() + " is not in active, activing it");
			MyTrain ret = new MyTrain ( mLocos[mCurLoc] );
			ret.getConductor().requestThrottle();
			MyTrainsInstance.getInstance().add(ret);
			return ret;
		}
	}

	public void moveCursorTo(MyBrowsableElement elt) {
		MyLocomotive loc = (MyLocomotive) elt;
		int i = 0;
		while ((i<mLocos.length) && (mLocos[i]!=loc))
				i++;
		if ( (i<mLocos.length) && (! MyTrainsInstance.getInstance().contains(mLocos[mCurLoc])))
			mCurLoc = i;
	}	
}
